package cn.edu.swu.miniwebsvr.core;

import java.io.InputStream;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class HttpParser {

    public static Parameter parse(InputStream inputStream) throws IOException {
        Parameter parameter = new Parameter();
        // TODO: [222024321072050/邓琳馨]
        // 1. 读取并解析 HTTP 请求行 (e.g., GET /path?param=value HTTP/1.1)
        //    - 设置 parameter.setMethod()
        //    - 设置 parameter.setUrl()，并解析出 URL 参数 (e.g., ?param=value)，存入 parameter.urlParams

        // 2. 循环读取并解析所有 HTTP 请求头 (e.g., Host: localhost:8080)
        //    - 存入 parameter.headers

        // 3. 根据请求方法 (Method) 和请求头 (Content-Length, Content-Type) 判断并读取请求体
        //    - 适用于 POST 请求，解析请求体中的参数，存入 parameter.bodyParams

        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));

        // 1. 解析请求行
        String requestLine = reader.readLine();
        if (requestLine == null || requestLine.isEmpty()) {
            return null; // 空请求
        }

        System.out.println("请求行: " + requestLine);

        // 解析请求方法、URL和协议版本
        String[] requestParts = requestLine.split(" ");
        if (requestParts.length < 3) {
            return null; // 无效的请求行
        }

        String method = requestParts[0].toUpperCase();
        String url = requestParts[1];
        String protocol = requestParts[2];

        parameter.setMethod(method);

        // 解析URL和查询参数
        parseUrlAndQueryParams(parameter, url);

        // 2. 解析请求头
        parseHeaders(parameter, reader);

        // 3. 解析请求体（如果是POST/PUT等方法）
        parseRequestBody(parameter, reader);

        return parameter;
    }

    /**
     * 解析URL和查询参数
     */
    private static void parseUrlAndQueryParams(Parameter parameter, String url) {
        try {
            // 分离URL路径和查询字符串
            String[] urlParts = url.split("\\?", 2);
            String path = urlParts[0];

            // 设置URL路径
            parameter.setUrl(path);

            // 解析查询参数
            if (urlParts.length > 1) {
                String queryString = urlParts[1];
                Map<String, String> queryParams = parseQueryString(queryString);
                for (Map.Entry<String, String> entry : queryParams.entrySet()) {
                    parameter.addUrlParam(entry.getKey(), entry.getValue());
                }
            }
        } catch (Exception e) {
            System.err.println("解析URL参数时发生错误: " + e.getMessage());
        }
    }

    /**
     * 解析查询字符串
     */
    private static Map<String, String> parseQueryString(String queryString) {
        Map<String, String> params = new HashMap<>();
        if (queryString == null || queryString.isEmpty()) {
            return params;
        }

        try {
            String[] pairs = queryString.split("&");
            for (String pair : pairs) {
                String[] keyValue = pair.split("=", 2);
                String key = URLDecoder.decode(keyValue[0], StandardCharsets.UTF_8.name());
                String value = keyValue.length > 1 ?
                        URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8.name()) : "";
                params.put(key, value);
            }
        } catch (Exception e) {
            System.err.println("解析查询字符串时发生错误: " + e.getMessage());
        }

        return params;
    }

    /**
     * 解析请求头
     */
    private static void parseHeaders(Parameter parameter, BufferedReader reader) throws IOException {
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.isEmpty()) {
                break; // 空行表示头部结束
            }

            // 解析头部字段
            int colonIndex = line.indexOf(':');
            if (colonIndex > 0) {
                String key = line.substring(0, colonIndex).trim();
                String value = line.substring(colonIndex + 1).trim();
                parameter.addHeader(key, value);

                System.out.println("请求头: " + key + ": " + value);
            }
        }
    }

    /**
     * 解析请求体
     */
    private static void parseRequestBody(Parameter parameter, BufferedReader reader) throws IOException {
        String method = parameter.getMethod();

        // 只有POST、PUT等方法可能有请求体
        if (!"POST".equals(method) && !"PUT".equals(method) && !"PATCH".equals(method)) {
            return;
        }

        // 检查Content-Length
        String contentLengthHeader = parameter.getHeader("Content-Length");
        if (contentLengthHeader == null || contentLengthHeader.isEmpty()) {
            return; // 没有Content-Length头
        }

        try {
            int contentLength = Integer.parseInt(contentLengthHeader);
            if (contentLength <= 0) {
                return;
            }

            // 读取请求体
            char[] bodyChars = new char[contentLength];
            int bytesRead = reader.read(bodyChars, 0, contentLength);
            if (bytesRead != contentLength) {
                System.err.println("警告: 实际读取的请求体长度与Content-Length不符");
            }

            String requestBody = new String(bodyChars, 0, bytesRead);
            System.out.println("请求体: " + requestBody);

            // 根据Content-Type解析请求体
            String contentType = parameter.getHeader("Content-Type");
            if (contentType != null && contentType.contains("application/x-www-form-urlencoded")) {
                // 解析表单数据
                Map<String, String> bodyParams = parseQueryString(requestBody);
                for (Map.Entry<String, String> entry : bodyParams.entrySet()) {
                    parameter.addBodyParam(entry.getKey(), entry.getValue());
                }
            } else {
                // 其他类型的请求体，暂时作为原始文本处理
                parameter.addBodyParam("_raw_body", requestBody);
            }

        } catch (NumberFormatException e) {
            System.err.println("无效的Content-Length: " + contentLengthHeader);
        }
    }

    /**
     * URL解码辅助方法
     */
    public static String urlDecode(String encoded) {
        try {
            return URLDecoder.decode(encoded, StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            System.err.println("URL解码失败: " + encoded);
            return encoded;
        }
    }

    /**
     * 解析键值对字符串的辅助方法
     */
    public static Map<String, String> parseKeyValueString(String data, String pairSeparator, String keyValueSeparator) {
        Map<String, String> result = new HashMap<>();
        if (data == null || data.isEmpty()) {
            return result;
        }

        String[] pairs = data.split(pairSeparator);
        for (String pair : pairs) {
            String[] keyValue = pair.split(keyValueSeparator, 2);
            if (keyValue.length >= 1) {
                String key = urlDecode(keyValue[0].trim());
                String value = keyValue.length > 1 ? urlDecode(keyValue[1].trim()) : "";
                result.put(key, value);
            }
        }

        return result;
    }
}